package PEARWARE.automataEsclavo1.impl;

import java.net.MalformedURLException;
import PEARWARE.comunicacion.mensajes.*;
import PEARWARE.comunicacion.*;

import java.rmi.RemoteException;

/**
 * Clase que representa el estado del sistema mueve un eje y un engranaje desde
 * las cintas a la estacion de montaje
 * 
 * @author Ricardo Vilchez Garcia.
 * @version 10/06/2012
 */

public class EstadoCogerPiezas extends IEstado implements MensajeVisitor {
	private boolean _estadoR1;
	private boolean _ejeColocado;
	private boolean _engranajeColocado;
	private int _tiempoEjecucion;
	private boolean waitForNextTurn;

	/**
	 * Constructor publico de la clase
	 */
	public EstadoCogerPiezas() {
		Elementos.getElementos().setResumen("R1 -> INICIO MOVER PIEZAS");
		System.out.println("ESTADO COGER PIEZAS");
		setEstado("ESTADO COGER PIEZAS");
		Elementos.getElementos().getRobot1().setCargado(false);
		Elementos.getElementos().getRobot1().activar();

		_ejeColocado = false;
		_engranajeColocado = false;
		_tiempoEjecucion = 0;

		waitForNextTurn = true;
	}

	/**
	 * Ejecucion principal del estado
	 */
	public void ejecutarAccion() {
		// Obtener mensajes y ejecutar acciones oportunas.
		Mensaje mensaje;
		while ((mensaje = Elementos.getElementos().get_buzonesMaestro()
				.recibirMensaje()) != null) {
			try {
				mensaje.accept(this);
				Elementos.getElementos().setMensajeRecibido(true);
			} catch (RemoteException e) {
				Elementos.getElementos().setResumen("Intentando reconectar.");
				try {
					Elementos.getElementos().conectar();
				} catch (RemoteException ee) {
				} catch (MalformedURLException ee) {
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
		}

		// Get sensores
		_estadoR1 = Elementos.getElementos().getRobot1().isMoving(); // should
																		// be
		// Ejecutar la accion de este estado.
		if (!_ejeColocado) {
			int tiempo_reloj = Configuracion.getConfiguracion()
					.get_tiempoReloj();
			_tiempoEjecucion = _tiempoEjecucion + tiempo_reloj;
			if (_tiempoEjecucion >= Configuracion.getConfiguracion()
					.get_tiempoRecogidaEje()) {
				_ejeColocado = true;
				Elementos.getElementos().getRobot1().setCargado(false);
				Elementos.getElementos().getRobot1().setOrientacion((byte) -1);
				Elementos.getElementos().setResumen("R1 -> EJE MOVIDO");
				Elementos.getElementos().getEstacionMontaje()
						.get_sensorPresenciaEje().setActivo(true);
				Elementos.getElementos().getCintaEjes().quitarUltimo();

				_tiempoEjecucion = 0;
			} else if (_tiempoEjecucion >= (Configuracion.getConfiguracion()
					.get_tiempoRecogidaEje()) / 2) {
				_ejeColocado = false;
				Elementos.getElementos().getRobot1().setCargado(true);
				Elementos.getElementos().getRobot1().setOrientacion((byte) 2);
				Elementos.getElementos().getCintaEjes().quitarUltimo();
			} else {
				Elementos.getElementos().getRobot1().setOrientacion((byte) 0);
			}
		}

		// Ejecutar la accion de este estado.
		if (_ejeColocado) {
			if (!waitForNextTurn) {
				if (_estadoR1 && _ejeColocado && !_engranajeColocado) {
					_tiempoEjecucion = _tiempoEjecucion
							+ Configuracion.getConfiguracion()
									.get_tiempoReloj();
					if (_tiempoEjecucion >= Configuracion.getConfiguracion()
							.get_tiempoRecogidaEng()) {
						_engranajeColocado = true;
						Elementos.getElementos().getRobot1().setCargado(false);
						Elementos.getElementos().getEstacionMontaje()
								.get_sensorPresenciaEngranaje().setActivo(true);
						Elementos.getElementos().getRobot1()
								.setOrientacion((byte) -1);
						Elementos.getElementos().getCintaEngranajes()
								.quitarUltimo();
						Elementos.getElementos().setResumen(
								"R1 -> ENGRANAJE MOVIDO");
					} else if (_tiempoEjecucion >= (Configuracion
							.getConfiguracion().get_tiempoRecogidaEng()) / 2) {
						_engranajeColocado = false;
						Elementos.getElementos().getRobot1().setCargado(true);
						Elementos.getElementos().getRobot1()
								.setOrientacion((byte) 2);
						Elementos.getElementos().getCintaEngranajes()
								.quitarUltimo();
					} else {
						Elementos.getElementos().getRobot1()
								.setOrientacion((byte) 1);
					}
				}
			} else
				waitForNextTurn = false;

		}

		// Enviar estado del automata. Incluir _carga, oriendtacion robot
		MensajeEstadoAutomataEsclavo1 estado = new MensajeEstadoAutomataEsclavo1(
				Elementos.getElementos().getCintaEjes().isMoving(), Elementos
						.getElementos().getCintaEjes().getVelocidad(),
				Elementos.getElementos().getCintaEjes().isLlena(), Elementos
						.getElementos().getCintaEjes().hayPiezaFinal(),
				Elementos.getElementos().getCintaEjes().getPosiciones(),
				Elementos.getElementos().getCintaEngranajes().isMoving(),
				Elementos.getElementos().getCintaEngranajes().getVelocidad(),
				Elementos.getElementos().getCintaEngranajes().isLlena(),
				Elementos.getElementos().getCintaEngranajes().hayPiezaFinal(),
				Elementos.getElementos().getCintaEngranajes().getPosiciones(),
				Elementos.getElementos().getRobot1().isMoving(), Elementos
						.getElementos().getRobot1().getOrientacion(), Elementos
						.getElementos().getRobot1().isCargado(), Elementos
						.getElementos().getEstacionMontaje().isActivo(),
				Elementos.getElementos().getEstacionMontaje()
						.get_sensorPresenciaEje().getActivo(), Elementos
						.getElementos().getEstacionMontaje()
						.get_sensorPresenciaEngranaje().getActivo(), false,
				Elementos.getElementos().getResumen());

		Elementos.getElementos().get_buzonesMaestro().enviarMensaje(estado);
	}

	/**
	 * Reliza el proceso de transicion del diagrama de estadps dependiendo de si
	 * el estado ha terminado su ejecucion
	 */
	public IEstado ejecutarTransicion() {
		if (Elementos.getElementos().isParada()
				&& Elementos.getElementos().isEmergencia()) {
			Elementos.getElementos().setEstadoBackup(this);

			return new EstadoParado();
		} else {
			if (_ejeColocado && _engranajeColocado) {
				Elementos.getElementos().getRobot1().parar();
				Elementos.getElementos().setResumen("R1 FIN MOVER PIEZAS EM");
				return new EstadoMontaje();
			} else {
				return this;
			}
		}
	}

	public void visit(MensajeArranqueMaestro m) {
		Elementos.getElementos().setResumen("RECIBIDA ORDEN ARRANQUE");
		System.out.println("RECIBIDA ORDEN DE ARRANQUE");
		Elementos.getElementos().getRobot1().setCargado(true);
		Elementos.getElementos().setParada(false);
		Elementos.getElementos().setEmergencia(false);
	}

	/**
	 * Visit del mensaje MensajeParadaMaestro
	 */
	public void visit(MensajeParadaMaestro m) {
		System.out.println("RECIBIDA ORDEN DE PARADA");
		Elementos.getElementos().setResumen("RECIBIDA ORDEN PARADA");
		Elementos.getElementos().getRobot1().setCargado(false);
		Elementos.getElementos().setRecoveryMode(false);
		Elementos.getElementos().getCintaEjes().pararCinta();
		Elementos.getElementos().getCintaEngranajes().pararCinta();
		Elementos.getElementos().setParada(true);
		Elementos.getElementos().setEmergencia(m.isEmergencia());
		if(m.getCaido() != -1){
			Elementos.getElementos().setCaida(true);
			System.exit(0);
		}
	}

}
